/// Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.Windows.Forms;
using NUnit.Framework;
using NUnit.Extensions.Forms;
using Microsoft.VSPowerToys.PackInstaller;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Diagnostics;

namespace GUITestScenarios
{
    [TestFixture]
    public class DeclineLicenseTests : NUnitFormTest
    {
        #region Private Data and Methods
        private PackInstallerForm packInstallForm;
        private ErrorMessages errorMessages;

        /// <summary>
        /// In order to test forms with ShowDialog under NUnitForms, you have to
        /// provide a "handler" method for the Form. Normally, this handler would
        /// contain the test logic. But, that doesn't work well for the PackInstaller
        /// because it uses threads. 
        /// 
        /// So, the test logic will be in a delegate method attched to the PackInstaller 
        /// form. Therefore, this is a skeleton handler and used for most tests.
        /// </summary>
        private void GenericFormHandler()
        {
        }
        #endregion

        [TestFixtureSetUp]
        public void Init()
        {
            Process[] visualStudioProcesses = Process.GetProcessesByName("devenv");
            TextWriter errorWriter = Console.Error;
            if (visualStudioProcesses.Length != 0)
            {
                errorWriter.WriteLine("You must close Visual Studio before running the test suite.");
                Assert.IsTrue(false);
            }
        }

        #region Click Decline License Button
        /// <summary>
        /// This test clicks the I Decline button on the license agreement form
        /// It verifies the test plan's License Terms Dialog scenario #3
        /// </summary>
        [Test]
        public void DeclineLicenseTest()
        {
            errorMessages = new ErrorMessages();
            packInstallForm = new PackInstallerForm(TestStrings.GeneralTestPackFeedXml);
            packInstallForm.OnPacksLoaded += new EventHandler<EventArgs>(DeclineLicenseHandler);
            ExpectModal("PackInstallerForm", "GenericFormHandler");

            // Need an ExpectModal to handle the license download and agreement forms.
            // If we decline the license we do NOT expect a progress form to be displayed
            // so we intentionally do not put an ExpectModal for it. Then, if one is displayed 
            // the test will fail due to the unexpected dialog form showing up.
            ExpectModal("LicenseAgreementDownloadForm", "GenericFormHandler");
            ExpectModal("MultipleLicenseAgreementForm", "DeclineLicenseFormHandler");

            packInstallForm.ShowDialog();
            errorMessages.printErrors("DeclineLicenseTest");
            Assert.AreEqual(0, errorMessages.Count, "DeclineLicenseTest failed. Check Console output for error messages.");
        }

        /// <summary>
        /// The generic OnPacksLoaded callback for the Decline license tests
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DeclineLicenseHandler(object sender, EventArgs e)
        {
            ButtonTester installSoftwareButtonTester = new ButtonTester("installSoftwareButton", "PackInstallerForm");
            PanelControlTester packListControlTester = new PanelControlTester("packListPanel", "PackInstallerForm");

            // Check the box to install the Managed Stack Explorer
            CheckBoxTester ManagedStackExplorertoolCheckBoxTester = new CheckBoxTester("Tools and Utilities.toolsPanel.Managed Stack Explorer.layoutPanel.installToolCheckBox", "PackInstallerForm");
            ManagedStackExplorertoolCheckBoxTester.Click();

            // Verify that the Install button is now enabled
            if (installSoftwareButtonTester.Properties.Enabled != true)
            {
                errorMessages.Add("Install software button is disabled after one tool was selected.");
            }

            installSoftwareButtonTester.Click();

            // Should return here after the license is declined or whatever.
            ButtonTester exitButtonTester = new ButtonTester("exitButton", "PackInstallerForm");
            exitButtonTester.Click();
        }

        private void DeclineLicenseFormHandler()
        {
            ButtonTester buttonTester = new ButtonTester("declineButton", "MultipleLicenseAgreementForm");
            FormTester ft = new FormTester("MultipleLicenseAgreementForm");

            // Verify that the decline button has been selected
            if (ft.Properties.ActiveControl == null)
                errorMessages.Add("Active control is null");
            else if (ft.Properties.ActiveControl.Name != "declineButton")
                errorMessages.Add("Active control is " + ft.Properties.ActiveControl.Name + " instead of declineButton");
            
            // Check the text of the decline button
            if (buttonTester.Text != "I &Decline")
            {
                errorMessages.Add("License Form decline button text is wrong: '" + buttonTester.Text + "'");
            }
            buttonTester.Click();
        }

        #endregion

        #region Click Form's Accept Button
        /// <summary>
        /// This test clicks the Form's Accept button which is the same as 
        /// clicking Enter.
        /// This test along with the ClickEscapeOnLicenseFormTest verifies 
        /// the test plan's License Terms Dialog scenario #2
        /// </summary>
        [Test]
        public void ClickEnterOnLicenseFormTest()
        {
            errorMessages = new ErrorMessages();
            packInstallForm = new PackInstallerForm(TestStrings.GeneralTestPackFeedXml);
            packInstallForm.OnPacksLoaded += new EventHandler<EventArgs>(DeclineLicenseHandler);
            ExpectModal("PackInstallerForm", "GenericFormHandler");

            // Need an ExpectModal to handle the license download and agreement forms.
            // If we decline the license we do NOT expect a progress form to be displayed
            // so we intentionally do not put an ExpectModal for it. Then, if one is displayed 
            // the test will fail due to the unexpected dialog form showing up.
            ExpectModal("LicenseAgreementDownloadForm", "GenericFormHandler");
            ExpectModal("MultipleLicenseAgreementForm", "ClickEnterLicenseFormHandler");

            packInstallForm.ShowDialog();
            errorMessages.printErrors("ClickEnterOnLicenseFormTest");
            Assert.AreEqual(0, errorMessages.Count, "ClickEnterOnLicenseFormTest failed. Check Console output for error messages.");
        }

        private void ClickEnterLicenseFormHandler()
        {
            FormTester formTester = new FormTester("MultipleLicenseAgreementForm");
            formTester.Properties.AcceptButton.PerformClick();
        }
        #endregion

        #region Clicks  Form's Cancel Button
        /// <summary>
        /// This test clicks the Form's Cancel button which is the same as 
        /// clicking Enter.
        /// This test along with the ClickEnterOnLicenseFormTest verifies 
        /// the test plan's License Terms Dialog scenario #2
        /// </summary>
        [Test]
        public void ClickEscapeOnLicenseFormTest()
        {
            errorMessages = new ErrorMessages();
            packInstallForm = new PackInstallerForm(TestStrings.GeneralTestPackFeedXml);
            packInstallForm.OnPacksLoaded += new EventHandler<EventArgs>(DeclineLicenseHandler);
            ExpectModal("PackInstallerForm", "GenericFormHandler");

            // Need an ExpectModal to handle the license download and agreement forms.
            // If we decline the license we do NOT expect a progress form to be displayed
            // so we intentionally do not put an ExpectModal for it. Then, if one is displayed 
            // the test will fail due to the unexpected dialog form showing up.
            ExpectModal("LicenseAgreementDownloadForm", "GenericFormHandler");
            ExpectModal("MultipleLicenseAgreementForm", "ClickEscapeLicenseFormHandler");

            packInstallForm.ShowDialog();
            errorMessages.printErrors("ClickEscapeOnLicenseFormTest");
            Assert.AreEqual(0, errorMessages.Count, "ClickEscapeOnLicenseFormTest failed. Check Console output for error messages.");
        }

        public void ClickEscapeLicenseFormHandler()
        {
            FormTester formTester = new FormTester("MultipleLicenseAgreementForm");
            formTester.Properties.CancelButton.PerformClick();
        }
        #endregion

        #region Close License Form
        [Test]
        public void CloseLicenseFormTest()
        {
            errorMessages = new ErrorMessages();
            packInstallForm = new PackInstallerForm(TestStrings.GeneralTestPackFeedXml);
            packInstallForm.OnPacksLoaded += new EventHandler<EventArgs>(DeclineLicenseHandler);
            ExpectModal("PackInstallerForm", "GenericFormHandler");

            // Need an ExpectModal to handle the license download and agreement forms.
            // If we decline the license we do NOT expect a progress form to be displayed
            // so we intentionally do not put an ExpectModal for it. Then, if one is displayed 
            // the test will fail due to the unexpected dialog form showing up.
            ExpectModal("LicenseAgreementDownloadForm", "GenericFormHandler");
            ExpectModal("MultipleLicenseAgreementForm", "CloseLicenseFormHandler");

            packInstallForm.ShowDialog();
            errorMessages.printErrors("CloseLicenseFormTest");
            Assert.AreEqual(0, errorMessages.Count, "CloseLicenseFormTest failed. Check Console output for error messages.");
        }

        public void CloseLicenseFormHandler()
        {
            FormTester tester = new FormTester("MultipleLicenseAgreementForm");
            tester.Close();
        }
        #endregion

    }
}
